; ** por compatibilidad se omiten tildes **
; ==============================================================================
; TRABAJO PRACTICO 3 - System Programming - ORGANIZACION DE COMPUTADOR II - FCEN
; ==============================================================================
; definicion de rutinas de atencion de interrupciones

BITS 32

%include "macrosmodoprotegido.mac"

%define SET_PAGE         286
%define GET_CODE_STACK   386

extern fin_intr_pic1

global _isr0
global _isr1
global _isr2
global _isr3
global _isr4
global _isr5
global _isr6
global _isr7
global _isr8
global _isr9
global _isr10
global _isr11
global _isr12
global _isr13
global _isr14
global _isr15
global _isr16
global _isr17
global _isr18
global _isr19

global _isr32
global _isr33
global _isr45

; definicion de las rutinas de atencion de interrupciones
; Largo de los mensajes: 31 caracteres, 
isr0mensaje:  db 'Divide by Zero                 '
isr1mensaje:  db 'Reserved for Intel use only    '
isr2mensaje:  db 'Nonmaskable External Interrupt '
isr3mensaje:  db 'Breakpoint                     '
isr4mensaje:  db 'Overflow                       '
isr5mensaje:  db 'Bound Range Exceeded           '
isr6mensaje:  db 'Invalid Opcode                 '
isr7mensaje:  db 'No Math Coprocessor            '
isr8mensaje:  db 'Double Fault                   '
isr9mensaje:  db 'Coprocessor Segment Overrun    '
isr10mensaje: db 'Invalid TSS                    '
isr11mensaje: db 'Segment Not Present            '
isr12mensaje: db 'Stack Segment Fault            '
isr13mensaje: db 'General Protection Fault       '
isr14mensaje: db 'Page Fault                     '
isr15mensaje: db 'Reserved for Intel use only    '
isr16mensaje: db 'x87 FPU Floating-Point Error   '
isr17mensaje: db 'Alignment Check                '
isr18mensaje: db 'Machine Check                  '
isr19mensaje: db 'SIMD Floating-Point Exception  ' 

%define color 0x2F

_isr0:
	mov edx, isr0mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr1:
	mov edx, isr1mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr2:
	mov edx, isr2mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr3:
	mov edx, isr3mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr4:
	mov edx, isr4mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr5:
	mov edx, isr5mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr6:
	mov edx, isr6mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr7:
	mov edx, isr7mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr8:
	mov edx, isr8mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr9:
	mov edx, isr9mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr10:
	mov edx, isr10mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr11:
	mov edx, isr11mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr12:
	mov edx, isr12mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr13:
	mov edx, isr13mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr14:
	mov edx, isr14mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr15:
	mov edx, isr15mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr16:
	mov edx, isr16mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr17:
	mov edx, isr17mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr18:
	mov edx, isr18mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

_isr19:
	mov edx, isr19mensaje
	IMPRIMIR_TEXTO edx, 31, color, 2, 43
	jmp $

; rutina de RELOJ
_isr32:
	cli 				;Deshabilitamos las interrupciones
	pushad				;Preservamos los registros
	call fin_intr_pic1	;Comunicamos al PIC que ya se atendió la interrupcion
	call proximo_reloj	;Llamamos a la funcion proximo_reloj
	popad				;Restauramos los registros
	sti					;Habilitamos las interrupciones
	iret				;Retornamos de la interrupcion
	
; rutina de TECLADO
_isr33:
	cli					;Deshabilitamos las interrupciones
	pushad				;Preservamos los registros
	call fin_intr_pic1	;Comunicamos al PIC que ya se atendió la interrupcion		
	call numeroTeclado	;Escribimos el numero por pantalla
	popad				;Restauramos los registros
	sti					;Habilitamos las interrupciones
	iret				;Retornamos de la interrupcion

; rutina de SERVICIOS
_isr45:
	cli					;Deshabilitamos las interrupciones
	pushad				;Preservamos los registros
	call fin_intr_pic1	;Comunicamos al PIC que ya se atendió la interrupcion		
	popad				;Restauramos los registros
	mov eax, 42			;Cambiamos el valor de eax por 42	
	sti					;Habilitamos las interrupciones
	iret				;Retornamos de la interrupcion

; rutina del reloj
proximo_reloj:
	pushad
	inc DWORD [isrnumero]
	mov ebx, [isrnumero]
	cmp ebx, 0x4
	jl .ok
		mov DWORD [isrnumero], 0x0
		mov ebx, 0
	.ok:
		add ebx, isrClock
		IMPRIMIR_TEXTO ebx, 1, 0x0f, 24, 79
	popad
	ret
	
isrnumero: dd 0x00000000
isrClock:  db '|/-\'

; rutina del teclado para escribir numeros
numeroTeclado:
	pushad
	xor eax, eax
	in al, 0x60		;Leemos el teclado a través del puerto 0x60, tenemos en al el scan code
	test al, 0x80	;Vemos si es makecode o breakcode
	je .es_makecode
	
	;es Breakcode
	xor eax, eax
	add eax, isrVacio
	IMPRIMIR_TEXTO eax, 1, 0x00, 0, 79	;Imprimimos el cuadrado negro como estaba antes
	jmp .fin
	
.es_makecode:
	cmp al, 0x02
	jl .fin			;si es escape o error salimos
	cmp al, 0x0b
	jg .fin			;si es mayor no corresponde a un numero
	dec al
	dec al			;restamos dos para que quede mapeado con nuestro string
	add eax, isrKeyboard
	IMPRIMIR_TEXTO eax, 1, 0x0F, 0, 79
		
.fin:
	popad
	ret
	
isrKeyboard:  db '1234567890'
isrVacio:  db ' '
